package org.javaforever.oville;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class Intercepter {
	
	public Action intercepte(Statement st) throws ValidateException{
		String input = st.getContent();
		//System.out.println("JerryDebug:"+input+":"+splitStringWithQuoteAndBlank(input).size()+":"+input.split(" ").length);
		if (input.startsWith("quit")) {
			Action ac = new Action();
			ac.setActionName("quit");
			return ac;
		}
		if (input.startsWith("setPrompt")&& input.split(" ").length >= 2) {
			Action ac = new Action();
			ac.setActionName("setPrompt");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("prompt", input.substring(9,input.length()).trim());
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("resetPrompt")) {
			Action ac = new Action();
			ac.setActionName("resetPrompt");
			return ac;
		}
		if (input.startsWith("codeWord")&& input.split(" ").length == 2) {
			Action ac = new Action();
			ac.setActionName("codeWord");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("narrowWord", input.split(" " )[1]);
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("codeWord")&& input.split(" ").length == 3) {
			Action ac = new Action();
			ac.setActionName("codeWordAssgin");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("narrowWord", input.split(" " )[1]);
			params.put("varName", input.split(" " )[2]);
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("code")) {
			Action ac = new Action();
			ac.setActionName("code");
			Map<String,String> params = new TreeMap<String,String>();
			String [] inputs = input.split("(\\s+=*\\s*|\\s*=+\\s*)");
			if (inputs.length == 2)params.put("narrowWords", input.split(" " )[1]);
			if (inputs.length == 4 && inputs[1].equals("var")) {
				params.put("narrowWords", inputs[3]);
				params.put("varName", inputs[2]);
				params.put(inputs[2], inputs[3]);
			}
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("decode")) {
			Action ac = new Action();
			ac.setActionName("decode");
			Map<String,String> params = new TreeMap<String,String>();
			String [] inputs = input.split("\\s+");
			if (inputs.length == 3 && inputs[1].equals("var")) {
				params.put("varName", inputs[2]);
			}
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("monkeyTest.monkeyNarrowWord")) {
			Action ac = new Action();
			ac.setActionName("monkeyTest.monkeyNarrowWord");
			return ac;
		}
		if (input.startsWith("monkeyTest.monkeyWord")) {
			Action ac = new Action();
			ac.setActionName("monkeyTest.monkeyWord");
			return ac;
		}
		if (input.startsWith("and")&& input.split(" ").length == 3) {
			Action ac = new Action();
			ac.setActionName("and");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("narrowWord1", input.split(" " )[1]);
			params.put("narrowWord2", input.split(" " )[2]);
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("or")&& input.split(" ").length == 3) {
			Action ac = new Action();
			ac.setActionName("or");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("narrowWord1", input.split(" " )[1]);
			params.put("narrowWord2", input.split(" " )[2]);
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("not")&& input.split(" ").length == 2) {
			Action ac = new Action();
			ac.setActionName("not");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("narrowWord", input.split(" " )[1]);
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("qAnd")&& input.split(" ").length == 3) {
			Action ac = new Action();
			ac.setActionName("qAnd");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("word1", input.split(" " )[1]);
			params.put("word2", input.split(" " )[2]);
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("qOr")&& input.split(" ").length == 3) {
			Action ac = new Action();
			ac.setActionName("qOr");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("word1", input.split(" " )[1]);
			params.put("word2", input.split(" " )[2]);
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("qNot")&& input.split(" ").length == 2) {
			Action ac = new Action();
			ac.setActionName("qNot");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("word", input.split(" " )[1]);
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("let")&& input.contains("toWords:")) {
			Action ac = new Action();
			ac.setActionName("letToWords");
			List<String> tokens = splitStringWithQuoteAndBlank(input);
			Map<String,String> params = new TreeMap<String,String>();
			params.put("resultVar", tokens.get(1));
			params.put("assignOps", tokens.get(2));
			params.put("var1", tokens.get(tokens.size()-1));
			if (tokens.get(3).startsWith("toWords")&&tokens.get(3).endsWith(":")&&tokens.get(4).length()==4) {
				params.put("ops", "toWords");
				params.put("pattern", tokens.get(4));
			}else if (tokens.get(3).startsWith("toWords")&&!tokens.get(3).endsWith(":")&&!tokens.get(3).contains(":")) {
				params.put("ops", "toWords");
				String [] ttokens = tokens.get(4).split(":");
				if (ttokens.length == 2 && ttokens[1].length()== 4) {
					params.put("pattern", ttokens[1]);
				}
			}else {
				throw new ValidateException("Wrong letToWords format.");
			}
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("let")&& input.contains("replaceTextWords:")) {
			Action ac = new Action();
			ac.setActionName("letReplaceTextWords");
			List<String> tokens = splitStringWithQuoteAndBlank(input);
			Map<String,String> params = new TreeMap<String,String>();
			params.put("resultVar", tokens.get(1));
			params.put("assignOps", tokens.get(2));
			params.put("var1", tokens.get(tokens.size()-1));
			if (tokens.get(3).startsWith("replaceTextWords")&&!input.contains("\"")) {
				params.put("ops", "replaceTextWords");
				String [] ttokens = tokens.get(3).split(":");
				if (ttokens.length == 3 && ttokens[1].length() == ttokens[2].length()) {
					params.put("pattern1", ttokens[1]);
					params.put("pattern2", ttokens[2]);
				}else {
					throw new ValidateException("Wrong letReplaceTextWords format.");
				}
			}else if (tokens.get(3).startsWith("replaceTextWords")&&tokens.get(3).endsWith(":")) {
				params.put("ops", "replaceTextWords");
				params.put("pattern1", tokens.get(4));
				if (":".equals(tokens.get(5))&&tokens.get(6).length() == tokens.get(4).length()) {
					params.put("pattern2", tokens.get(6));
				}else if (tokens.get(5).startsWith(":")&&tokens.get(5).length()==tokens.get(4).length()+1) {
					params.put("pattern2", tokens.get(5).substring(1,tokens.get(5).length()));
				}else {
					throw new ValidateException("Wrong letReplaceTextWords format.");
				}
			} else {
				throw new ValidateException("Wrong letToWards format.");
			}
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("let")&& input.split(" ").length == 6 && !input.contains("\"")) {
			Action ac = new Action();
			ac.setActionName("let");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("resultVar", input.split(" " )[1]);
			params.put("assignOps", input.split(" " )[2]);
			params.put("var1", input.split(" " )[3]);
			params.put("ops", input.split(" " )[4]);
			params.put("var2", input.split(" " )[5]);
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("let")&& input.split(" ").length == 5 && !input.contains("\"")) {
			Action ac = new Action();
			ac.setActionName("letSingle");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("resultVar", input.split(" " )[1]);
			params.put("assignOps", input.split(" " )[2]);
			params.put("ops", input.split(" " )[3]);
			params.put("var1", input.split(" " )[4]);
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("let")&& input.split(" ").length == 4 && input.contains("monkeyTest.") && !input.contains("\"")) {
			Action ac = new Action();
			ac.setActionName("letMonkey");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("resultVar", input.split(" " )[1]);
			params.put("assignOps", input.split(" " )[2]);
			params.put("ops", input.split(" " )[3]);
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("let")&& splitStringWithQuoteAndBlank(input).size() == 4) {
			Action ac = new Action();
			ac.setActionName("letAssign");
			List<String> tokens = splitStringWithQuoteAndBlank(input);
			Map<String,String> params = new TreeMap<String,String>();
			params.put("resultVar",tokens.get(1));
			params.put("assignOps", tokens.get(2));
			params.put("var1", tokens.get(3));
			params.put("containsQuote",""+input.contains("\""));
			ac.setParams(params);
			return ac;
		}
		
		if (input.startsWith("show")&& input.split(" ").length == 2) {
			Action ac = new Action();
			ac.setActionName("show");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("var1", input.split(" " )[1]);
			ac.setParams(params);
			return ac;
		}
		
		if (input.startsWith("write")&& input.split(" ").length == 3) {
			Action ac = new Action();
			ac.setActionName("write");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("var1", input.split(" " )[1]);
			params.put("filePath", input.split(" " )[2]);
			ac.setParams(params);
			return ac;
		}
		
		if (input.startsWith("load")&& input.split(" ").length == 2) {
			Action ac = new Action();
			ac.setActionName("load");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("fileName", input.split(" " )[1]);
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("run")&& input.split(" ").length == 2) {
			Action ac = new Action();
			ac.setActionName("run");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("scriptPath", input.split(" " )[1]);
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("return")&& input.split(" ").length == 2) {
			Action ac = new Action();
			ac.setActionName("return");
			Map<String,String> params = new TreeMap<String,String>();
			params.put("varMap", input.split(" " )[1]);
			ac.setParams(params);
			return ac;
		}
		if (input.startsWith("//")) {
			Action ac = new Action();
			ac.setActionName("comment");
			return ac;
		}
		return null;
	}
	
	public static void main(String [] argv) {
		String str = "let comment = \"=======================\"";
		List<String> strs = splitStringWithQuoteAndBlank(str);
		for (String st:strs) {
			System.out.println(st);	
		}
	}
	
	public static List<String> splitStringWithQuoteAndBlank(String str){
		String [] tokens = str.split("\"");
		List<String> results = new ArrayList<>();
		for (int i=0;i<tokens.length;i++) {
			if (i%2 == 0) {
				String [] tks = tokens[i].split(" ");
				for (String tk :tks) {
					if (!StringUtil.isBlank(tk)) results.add(tk);
				}
			}else {
				results.add(tokens[i]);
			}
		}
		return results;
	}
}
